package com.ayf.payment.game.api.controller;


import com.ayf.payment.game.api.dto.MerchantDTO;
import com.ayf.payment.game.api.dto.MerchantPayOrderDTO;
import com.ayf.payment.game.api.dto.PageDTO;
import com.ayf.payment.game.api.dto.PageInfoDTO;
import com.ayf.payment.game.api.dto.alipay.MerchantAlipayOrderDTO;
import com.ayf.payment.game.api.dto.criteria.MerchantAlipayOrderCriteria;
import com.ayf.payment.game.api.dto.criteria.MerchantBatchPayFileCriteria;
import com.ayf.payment.game.api.dto.criteria.MerchantPayOrderCriteria;
import com.ayf.payment.game.api.entity.*;
import com.ayf.payment.game.api.excel.ExcelUtils;
import com.ayf.payment.game.api.excel.UploadPayOrderData;
import com.ayf.payment.game.api.excel.UploadPayOrderListener;
import com.ayf.payment.game.api.excel.alipay.UploadAliPayOrderData;
import com.ayf.payment.game.api.excel.alipay.UploadAliPayOrderListener;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.service.*;
import com.ayf.payment.game.api.type.CommonConstants;
import com.ayf.payment.game.api.utils.CommonResult;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.swwx.charm.commons.lang.utils.BeanConvertUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

@RequestMapping("/v/merchant/pay/order")
@RestController
public class MerchantPayOrderController {

    @Autowired
    private MerchantPayOrderService merchantPayOrderService;
    @Autowired
    private MerchantAlipayOrderService merchantAlipayOrderService;
    @Autowired
    private MerchantAliBatchPayFileService merchantAliBatchPayFileService;
    @Autowired
    private MerchantAliBatchPayFileFailReasonService merchantAliBatchPayFileFailReasonService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private MerchantBatchPayFileService merchantBatchPayFileService;
    @Autowired
    private MerchantBatchPayFileFailReasonService merchantBatchPayFileFailReasonService;

    /**
     * 商户代付订单创建
     *
     * @param payOrderDTO
     * @return
     */
    @PostMapping("/create")
    public CommonResult<String> create(MerchantDTO merchantDTO, @RequestBody MerchantPayOrderDTO payOrderDTO) {
        if (payOrderDTO == null) {
            throw new ParameterException("参数不能为空");
        }
        if (payOrderDTO.getPayType() == null) {
            throw new ParameterException("付款类型不能为空");
        }
        if (StringUtils.isBlank(payOrderDTO.getAccountNo())) {
            throw new ParameterException("账号不能为空");
        }
        if (StringUtils.isBlank(payOrderDTO.getAccountName())) {
            throw new ParameterException("账号名称不能为空");
        }
        if (StringUtils.isBlank(payOrderDTO.getBankName())) {
            throw new ParameterException("银行名称不能为空");
        }
        if (payOrderDTO.getAmount() == null) {
            throw new ParameterException("金额不能为空");
        }
        if (payOrderDTO.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ParameterException("金额必须大于0元");
        }
        if (StringUtils.isEmpty(payOrderDTO.getPayPassword())) {
            throw new ParameterException("支付密码不能为空");
        }
        if (!merchantService.checkPayPassword(merchantDTO.getId(), payOrderDTO.getPayPassword())) {
            throw new ParameterException("支付密码错误");
        }
        if (payOrderDTO.getPayType().intValue()==2 && StringUtils.isEmpty(payOrderDTO.getRemark())){
            throw new ParameterException("付款方式为爱游宝时，付款描述不能为空，请填写游戏名称");
        }
        payOrderDTO.setMerchantId(merchantDTO.getId());
        return merchantPayOrderService.createPayOrder(merchantDTO, payOrderDTO);
    }

    /**
     * 商户代付订单记录查询
     *
     * @param merchantDTO
     * @param merchantPayOrderCriteria
     * @return
     */
    @PostMapping("/list")
    public CommonResult<PageInfoDTO> list(MerchantDTO merchantDTO, @RequestBody MerchantPayOrderCriteria merchantPayOrderCriteria) {
        if (merchantPayOrderCriteria == null) {
            throw new ParameterException("查询失败，参数不能为空");
        }
        merchantPayOrderCriteria.setMerchantId(merchantDTO.getId());
        PageInfoDTO<MerchantPayOrderDTO> pageDTO = merchantPayOrderService.getMerchantPayOrderListByPage(merchantPayOrderCriteria);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "登录成功", pageDTO);
    }

    /**
     * 批量代付文件上传
     *
     * @param file excel文件
     * @return
     */
    @PostMapping(value = "/bathPay", consumes = {"multipart/form-data"})
    public CommonResult<Object> bathPay(MerchantDTO merchantDTO, @RequestParam("payPassword") String payPassword,
                                        @RequestParam(value = "file") MultipartFile file) {
        String traceId = SnowFlakeUtils.getTraceId();
        if (StringUtils.isBlank(payPassword)) {
            throw new ParameterException("支付密码不能为空");
        }
        if (!merchantService.checkPayPassword(merchantDTO.getId(), payPassword)) {
            throw new ParameterException("支付密码错误");
        }
        if (file == null) {
            throw new ParameterException("导入Excel为空");
        }

        String suffixName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        suffixName = suffixName.toLowerCase();
        if (!"xls".equals(suffixName) && !"xlsx".equals(suffixName)) {
            LogPortal.error("{} 商户[{}]上传批量代付文件失败，文件格式错误，仅支持xls，当前文件格式：{}", traceId, merchantDTO.getId(), suffixName);
            throw new ParameterException("文件格式错误，仅支持xls或xlsx，错误码:" + traceId);
        }
        long fileSize = file.getSize();
        if (fileSize > 2097152) {
            LogPortal.error("{} 商户[{}]上传批量代付文件失败，文件大小超过2M，，当前文件大小：{}", traceId, merchantDTO.getId(), fileSize);
            throw new ParameterException("文件大小超过2M，错误码:" + traceId);
        }
        String fileName = file.getOriginalFilename();
        try {
            UploadPayOrderListener listener = new UploadPayOrderListener(traceId, merchantDTO.getId(), fileName, merchantPayOrderService);
            ExcelUtils.upload(traceId, file, 1, UploadPayOrderData.class, listener);
        } catch (ParameterException e) {
            return new CommonResult<>(CommonConstants.RETURN_ERROR, e.getMsg());
        } catch (Exception e) {
            LogPortal.error("{} 商户[{}]上传批量代付文件失败,发生[{}]异常，异常内容为[{}]", traceId, merchantDTO.getId(),
                    e.getClass().getName(), e.getMessage());
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "请确认上传的数据格式是否正确，您可以先下载示例查看数据格式。错误码：" + traceId);
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "批量代付文件上传成功");
    }

    /**
     * 商户代付文件记录查询
     *
     * @param merchantDTO
     * @param criteria
     * @return
     */
    @PostMapping("/batchFileList")
    public CommonResult<PageDTO> batchFileList(MerchantDTO merchantDTO,
                                               @RequestBody MerchantBatchPayFileCriteria criteria) {
        criteria.setMerchantId(merchantDTO.getId());
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<MerchantBatchPayFile> fileList = merchantBatchPayFileService.selectList(criteria);
        PageInfo<MerchantBatchPayFile> pageInfo = new PageInfo<>(fileList);
        PageDTO dto = BeanConvertUtils.convert(pageInfo, PageDTO.class);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "商户代付文件记录查询成功", dto);
    }

    /**
     * 商户代付文件错误信息查询
     *
     * @param criteria
     * @return
     */
    @PostMapping("/errorInfo")
    public CommonResult<List<MerchantBatchPayFileFailReason>> batchFileList2(@RequestBody MerchantBatchPayFileCriteria criteria) {
        if (StringUtils.isBlank(criteria.getFileId())) {
            throw new ParameterException("文件id不能为空");
        }
        List<MerchantBatchPayFileFailReason> fileList = merchantBatchPayFileFailReasonService.list(criteria.getFileId());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "商户代付文件错误信息查询成功", fileList);
    }

    /**
     * 支付宝批量代付文件上传
     *
     * @param file excel文件
     * @return
     */
    @PostMapping(value = "/bathAliPay", consumes = {"multipart/form-data"})
    public CommonResult<Object> bathAliPay(MerchantDTO merchantDTO, @RequestParam("payPassword") String payPassword,
                                           @RequestParam(value = "file") MultipartFile file) {
        String traceId = SnowFlakeUtils.getTraceId();
        if (StringUtils.isBlank(payPassword)) {
            throw new ParameterException("支付密码不能为空");
        }
        if (!merchantService.checkPayPassword(merchantDTO.getId(), payPassword)) {
            throw new ParameterException("支付密码错误");
        }
        if (file == null) {
            throw new ParameterException("导入Excel为空");
        }

        String suffixName = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        suffixName = suffixName.toLowerCase();
        if (!"xls".equals(suffixName) && !"xlsx".equals(suffixName)) {
            LogPortal.error("{} 商户[{}]上传批量代付文件失败，文件格式错误，仅支持xls或xlsx，当前文件格式：{}", traceId, merchantDTO.getId(), suffixName);
            throw new ParameterException("文件格式错误，仅支持xls或xlsx，错误码:" + traceId);
        }
        long fileSize = file.getSize();
        if (fileSize > 2097152) {
            LogPortal.error("{} 商户[{}]上传批量代付文件失败，文件大小超过2M，，当前文件大小：{}", traceId, merchantDTO.getId(), fileSize);
            throw new ParameterException("文件大小超过2M，错误码:" + traceId);
        }
        String fileName = file.getOriginalFilename();
        try {
            UploadAliPayOrderListener listener = new UploadAliPayOrderListener(traceId, merchantDTO.getId(), fileName, merchantAlipayOrderService);
            ExcelUtils.upload(traceId, file, 1, UploadAliPayOrderData.class, listener);
        } catch (ParameterException e) {
            return new CommonResult<>(CommonConstants.RETURN_ERROR, e.getMsg());
        } catch (Exception e) {
            LogPortal.error("{} 商户[{}]上传支付宝批量代付文件失败,发生[{}]异常，异常内容为[{}]", traceId, merchantDTO.getId(),
                    e.getClass().getName(), e.getMessage());
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "请确认上传的数据格式是否正确，您可以先下载示例查看数据格式。错误码：" + traceId);
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "支付宝批批量代付文件上传成功");
    }

    /**
     * 商户支付宝代付文件记录查询
     *
     * @param merchantDTO
     * @param criteria
     * @return
     */
    @PostMapping("/aliBatchFileList")
    public CommonResult<PageDTO> aliBatchFileList(MerchantDTO merchantDTO,
                                                  @RequestBody MerchantBatchPayFileCriteria criteria) {
        criteria.setMerchantId(merchantDTO.getId());
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<MerchantAliBatchPayFile> fileList = merchantAliBatchPayFileService.selectList(criteria);
        PageInfo<MerchantAliBatchPayFile> pageInfo = new PageInfo<>(fileList);
        PageDTO dto = BeanConvertUtils.convert(pageInfo, PageDTO.class);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "商户支付宝代付文件记录查询成功", dto);
    }

    /**
     * 商户支付宝代付文件错误信息查询
     *
     * @param criteria
     * @return
     */
    @PostMapping("/aliErrorInfo")
    public CommonResult<List<MerchantAliBatchPayFileFailReason>> aliErrorInfo(@RequestBody MerchantBatchPayFileCriteria criteria) {
        if (StringUtils.isBlank(criteria.getFileId())) {
            throw new ParameterException("文件id不能为空");
        }
        List<MerchantAliBatchPayFileFailReason> fileList = merchantAliBatchPayFileFailReasonService.list(criteria.getFileId());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "商户支付宝代付文件错误信息查询成功", fileList);
    }

    /**
     * 商户支付宝代付订单记录查询
     *
     * @param merchantDTO
     * @param criteria
     * @return
     */
    @PostMapping("/aliPayList")
    public CommonResult<PageDTO> aliPayList(MerchantDTO merchantDTO, @RequestBody MerchantAlipayOrderCriteria criteria) {
        criteria.setMerchantId(merchantDTO.getId());
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<MerchantAlipayOrderDTO> list = merchantAlipayOrderService.list(criteria);
        PageInfo<MerchantAlipayOrderDTO> pageInfo = new PageInfo<>(list);
        PageDTO dto = BeanConvertUtils.convert(pageInfo, PageDTO.class);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "商户支付宝代付订单记录查询成功", dto);
    }
}
